package com.fdl.dao.security;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.fdl.dao.base.Dao;
import com.fdl.dao.base.impl.BaseHibernateDao;
import com.fdl.dao.model.security.Permission;
import com.fdl.dao.model.security.Role;
import com.fdl.dao.model.security.User;

/**
 * 用户Dao 
 * @project: hb-intra
 * @Date:2010-8-4
 * @version  1.0
 * @Company: 33e9
 * @author zhangYong.huang
 */
public class UserDao extends BaseHibernateDao implements Dao {
	
	private NamedParameterJdbcTemplate jdbcTemplate;

	private static final String HQL_PERMIS_BY_USER = "select permi from Permission permi inner join " +
			"permi.roles as role inner join role.users as user where permi.status='1' and user=?";
	
	private static final String HQL_USERS_BY_PERMISSION = "select user from Permission permi " +
			"inner join permi.roles as role inner join role.users as user " +
			"where permi.status='1' and permi=?";
	
	private static final String HQL_USERS_BY_ROLE = "from User u where ? in elements(u.roles)";
	
	private static final String HQL_ALL_USER = "from User a where a.status!=-1 ";
	
	private static final String SQL_UPDATE_LOGIN_SUCCESS = "update hr_users set " +
			"login_times=login_times+1,last_login_address=:ipAddress," +
			"last_login_time=:lastLoginTime " +
			"where id=:id";
	
	private static final String HQL_USER_BY_LOGINID = "select count(*) from users u where u.loginid = ?";
	
	public void setJdbcTemplate(NamedParameterJdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	public UserDao() {
		super(User.class);
	}

	/**
	 * 根据ID获取用户
	 * @param id
	 * @return
	 */
	public User get(Serializable id) {
		return (User) super.load(id);
	}

	/**
	 * 通过User找出其相对应的所有合法的Permissions
	 */
	public List findPermisByUser(User user) {
		return getHibernateTemplate().find(HQL_PERMIS_BY_USER, user);
	}

	/**
	 * 通过Permission找出其相对应的所有合法的users
	 */
	public List findUsersByPermission(Permission permi) {
		return getHibernateTemplate().find(HQL_USERS_BY_PERMISSION, permi);
	}
	
	/**
	 * 获取所有非删除用户
	 * @return
	 */
	public List getUsersList() {
		return find(HQL_ALL_USER);
	}

	public List findBy(Map filter) {
		Criteria criteria = getSession().createCriteria(getEntityClass());

		String id = (String) filter.get("id");

		if (StringUtils.isNotBlank(id)) {
			criteria.add(Restrictions.eq("id", new Integer(id)));
		}

		String name = (String) filter.get("name");

		if (StringUtils.isNotBlank(name)) {
			criteria.add(Restrictions.like("name", "%" + name + "%"));
		}

		String loginid = (String) filter.get("loginid");

		if (StringUtils.isNotBlank(loginid)) {
			criteria.add(Restrictions.like("loginid", "%" + loginid + "%"));
		}

		String email = (String) filter.get("email");

		if (StringUtils.isNotBlank(email)) {
			criteria.add(Restrictions.like("email", "%" + email + "%"));
		}

		String status = (String) filter.get("status");

		if (StringUtils.isNotEmpty(status) && !"all".equals(status)) {
			criteria.add(Restrictions.eq("status", status));
		}

		criteria.addOrder(org.hibernate.criterion.Order.asc("id"));

		return criteria.list();
	}

	/**
	 * 根据登陆ID获取用户
	 * @param loginid
	 * @return
	 */
	public User loadUserByUserLoginID(String loginid) {
		return (User) findUniqueBy("loginid", loginid);
	}

	public int getCountWithSameLoginid(User user) {
		StringBuffer hqlSb = new StringBuffer(HQL_USER_BY_LOGINID);
		Object[] args;
		if (user.getId() == null) {
			args = new Object[] { user.getLoginid() };
		} else {
			hqlSb.append("and u != ?");
			args = new Object[] { user.getLoginid(), user };
		}
		return ((Long) findForObject(hqlSb.toString(), args)).intValue();
	}

	/**
	 * 根据角色获取用户
	 * @param role
	 * @param excludeStatus
	 * @return
	 */
	public List getUsersByRole(Role role, String[] excludeStatus) {
		StringBuffer hqlSB = new StringBuffer(HQL_USERS_BY_ROLE);
		int len = excludeStatus.length;

		Object[] args = new Object[len + 1];
		args[0] = role;

		for (int i = 0; i < len; i++) {
			hqlSB.append(" and u.status != ?");
			args[i + 1] = excludeStatus[i];
		}

		return find(hqlSB.toString(), args);
	}
	
	/**
	 * 登陆成功以后修改登陆IP地址、登陆时间、登陆次数
	 * @param id
	 * @param loginAddress
	 */
	public void onSuccessLogin(Serializable id,String loginAddress){
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("ipAddress", loginAddress);
		paramMap.put("lastLoginTime", new Date());
		paramMap.put("id", id);
		jdbcTemplate.update(SQL_UPDATE_LOGIN_SUCCESS, paramMap);
	}
}
